<script lang="ts" setup>
import type { ButtonProps, TooltipProps } from 'ant-design-vue'

import type { PropType } from 'vue'

import { computed, toRaw } from 'vue'

import { IconifyIcon } from '@vben/icons'
import { isBoolean, isFunction, isString } from '@vben/utils'

import { Button, Divider, Tooltip } from 'ant-design-vue'

import Dropdown from '#/components/Dropdown/src/Dropdown.vue'
import PopconfirmText from '#/components/TableAction/PopconfirmText.vue'
import { usePermission } from '#/hooks/usePermission'
import { overridesPreferences } from '#/preferences'

interface Fn<T = any, R = T> {
    (...arg: T[]): R
}

export interface PopConfirm {
    title: string
    okText?: string
    cancelText?: string
    onConfirm: Fn
    onCancel?: Fn
    icon?: string
    placement?:
        | 'bottom'
        | 'bottomLeft'
        | 'bottomRight'
        | 'left'
        | 'leftBottom'
        | 'leftTop'
        | 'right'
        | 'rightBottom'
        | 'rightTop'
        | 'top'
        | 'topLeft'
        | 'topRight'
}

export interface ActionItem extends ButtonProps {
    onClick?: Fn
    label?: string
    color?: string
    icon?: string
    popConfirm?: PopConfirm
    disabled?: boolean
    divider?: boolean
    // 权限编码控制是否显示
    auth?: string | string[]
    // 业务控制是否显示
    ifShow?: ((action: ActionItem) => boolean) | boolean
    tooltip?: string | TooltipProps
}

defineOptions({ name: 'TableAction' })

const props = defineProps({
    actions: {
        type: Array as PropType<ActionItem[]>,
        default: null
    },
    dropDownActions: {
        type: Array as PropType<ActionItem[]>,
        default: null
    },
    divider: {
        type: Boolean,
        default: true
    }
})
const { hasPermission } = usePermission()

const getActions = computed(() => {
    return (toRaw(props.actions) || [])
        .filter((action) => {
            return hasPermission(action.auth) && isIfShow(action)
        })
        .map((action) => {
            return {
                type: 'link',
                size: 'small',
                ...action
            }
        })
})

const getDropdownList = computed((): any[] => {
    const list = (toRaw(props.dropDownActions) || []).filter((action) => {
        return hasPermission(action.auth) && isIfShow(action)
    })
    return list.map((action, index) => {
        const { label, popConfirm } = action
        return {
            ...action,
            ...popConfirm,
            text: label,
            divider: index < list.length - 1 ? props.divider : false
        }
    })
})

function isIfShow(action: ActionItem): boolean {
    const ifShow = action.ifShow

    let isIfShow = true

    if (isBoolean(ifShow)) {
        isIfShow = ifShow
    }
    if (isFunction(ifShow)) {
        isIfShow = ifShow(action)
    }
    return isIfShow
}
function getTooltip(data: string | TooltipProps): TooltipProps {
    return {
        placement: 'bottom',
        ...(isString(data) ? { title: data } : data)
    }
}
function getColor(color?: string) {
    return color || overridesPreferences.theme?.colorPrimary
}
</script>

<template>
    <div>
        <template v-for="(action, index) in getActions" :key="index">
            <Tooltip
                v-if="action.tooltip"
                v-bind="getTooltip(action.tooltip)"
                class="cursor-pointer"
            >
                <PopconfirmText
                    v-bind="action.popConfirm"
                    :enable="!!action.popConfirm"
                    @click="action.onClick"
                >
                    <IconifyIcon
                        v-if="action.icon"
                        :color="getColor(action.color)"
                        :icon="action.icon"
                        height="18px"
                        style="display: inline-flex"
                    />
                    <span v-if="action.label" :style="{ color: getColor(action.color) }">
                        {{ action.label }}
                    </span>
                </PopconfirmText>
            </Tooltip>
            <span v-else class="cursor-pointer">
                <PopconfirmText
                    v-bind="action.popConfirm"
                    :enable="!!action.popConfirm"
                    @click="action.onClick"
                >
                    <IconifyIcon
                        v-if="action.icon"
                        :color="getColor(action.color)"
                        :icon="action.icon"
                        height="18px"
                        style="display: inline-flex"
                    />
                    <span v-if="action.label" :style="{ color: getColor(action.color) }">
                        {{ action.label }}
                    </span>
                </PopconfirmText>
            </span>
            <Divider
                v-if="divider && index < getActions.length - 1"
                class="action-divider"
                type="vertical"
            />
        </template>

        <Dropdown
            v-if="dropDownActions && getDropdownList.length > 0"
            :drop-menu-list="getDropdownList"
            :trigger="['hover']"
            popconfirm
        >
            <slot name="more"></slot>

            <Button v-if="!$slots.more" size="small" type="link">
                <IconifyIcon
                    color="#333"
                    height="18px"
                    icon="ant-design:more-outlined"
                    style="display: inline-flex"
                />
            </Button>
        </Dropdown>
    </div>
</template>
